/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package grafrajz;

import grafrajz.dialogs.NewEdgeWindow;
import grafrajz.dialogs.NewGraphWindow;
import grafrajz.dialogs.NewNodeWindow;
import grafrajz.utils.Edge;
import grafrajz.utils.Node;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;

/**
 *
 * @author adam_fejes_dell
 * 
 * A program ablaka
 */
public class GrafRajzWindow extends JFrame {

    final private int CANVAS_WIDTH = 800, CANVAS_HEIGHT = 750, NODE_SIZE = 50;
    private MyCanvas canvas;
    private GraphLogic graphLogic;
    private JPanel upperPanel, rightPanel;
    private JList nodesList, edgesList;
    private JButton deleteNodeBtn, deleteEdgeBtn, newNodeBtn, newEdgeBtn;
    private JLabel dataLabel;
    private JScrollPane scroll;
    private  JMenuBar menuBar;
    private JMenu menu;
    
    private DefaultListModel nodesModel, edgesModel;
    private JFileChooser fc;
    private File file;
    
    /**
     * A konstruktorban jön létre az összes grafika elem
     */
    GrafRajzWindow context;
    
    
    public GrafRajzWindow() {
        context = this;
        
        graphLogic = new GraphLogic(CANVAS_WIDTH, CANVAS_HEIGHT, NODE_SIZE, context);
        graphLogic.newGraph(true, true, false);
        graphLogic.addNode("A");
        graphLogic.addNode("B");
        graphLogic.addEdge("A", 1, "B");

        
        //Ablak tulajdonságai
        

        setSize(CANVAS_WIDTH + 200, CANVAS_HEIGHT);
        setLocation(30, 40);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        setTitle("GráfRajz");


        //Rajzterület
        canvas = new MyCanvas(graphLogic, NODE_SIZE);
        add(canvas, BorderLayout.CENTER);

        //Jobb oldali panel létrehozása
        rightPanel = new JPanel(new GridLayout(7, 1, 10, 10));
        rightPanel.setPreferredSize(new Dimension(300, CANVAS_HEIGHT));
        add(rightPanel, BorderLayout.EAST);

        //Felső menü
        menuBar = new JMenuBar();
        menu = new JMenu("Menü");
        menuBar.add(menu);
        menu.add(newGraphAction);
        menu.add(loadGraphAction);
        menu.add(saveGraphAction);
        menu.add(bejarasAction);

        //Felső menü tároló panel
        upperPanel = new JPanel();
        upperPanel.setLayout(new BorderLayout());
        upperPanel.add(menuBar, BorderLayout.WEST);
        add(upperPanel, BorderLayout.NORTH);


        //rightPanel elemei******************************

        //Csúcsválasztó
        //nodesList = new JList(graphLogic.getAllNodes().toArray());
        nodesModel = new DefaultListModel();
        ArrayList<Node> n = graphLogic.getAllNodes();
        for(Node node : n){
            nodesModel.addElement(node);
        }
        nodesList = new JList(nodesModel);
        scroll = new JScrollPane(nodesList);
        rightPanel.add(scroll);

        //Csúcs törlése
        deleteNodeBtn = new JButton("Csúcs törlése");
        deleteNodeBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //System.out.println("Delete node: " + nodesList.getSelectedValue().toString());
                if (nodesList.getSelectedValue() != null && graphLogic.removeNode(nodesList.getSelectedValue().toString())) {
                    //System.out.println("Node removed");
                    canvas.repaint();
                    nodesModel.removeElementAt(nodesList.getSelectedIndex());
                    
                    if(edgesModel != null){
                        edgesModel.removeAllElements();
                        
                        ArrayList<Edge> ed = graphLogic.getAllEdges();
                        //System.out.println("All edges: " + ed.size());
                        for(Edge edge : ed){
                            edgesModel.addElement(edge);
                        }
                        
                        edgesList.removeAll();
                        edgesList.setModel(edgesModel);
                    }
                    dataLabel.setText(buildDataLabelText());
                    rightPanel.repaint();
                    context.repaint();
                }
            }
        });
        deleteNodeBtn.setPreferredSize(new Dimension(100, 50));
        rightPanel.add(deleteNodeBtn);

        //Él választó
        edgesModel = new DefaultListModel();
        ArrayList<Edge> e = graphLogic.getAllEdges();
        for(Edge edge : e){
            edgesModel.addElement(edge);
        }
        edgesList = new JList(edgesModel);
        scroll = new JScrollPane(edgesList);
        rightPanel.add(scroll);

        //Él törlése
        deleteEdgeBtn = new JButton("Él törlése");
        deleteEdgeBtn.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (edgesList.getSelectedValue() != null && graphLogic.removeEdge((Edge)edgesList.getSelectedValue())) {
                    //System.out.println("Edge removed");
                    canvas.repaint();
                    edgesModel.removeElementAt(edgesList.getSelectedIndex());
                    dataLabel.setText(buildDataLabelText());
                    context.repaint();
                }
            }
        });
        rightPanel.add(deleteEdgeBtn);
        
        
        //új csúcs
        newNodeBtn = new JButton("Új csúcs");
        newNodeBtn.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                new NewNodeWindow(context, graphLogic).setVisible(true);
            }
        });
        rightPanel.add(newNodeBtn);
        
        //új él
        newEdgeBtn = new JButton("Új él");
        newEdgeBtn.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                new NewEdgeWindow(context, graphLogic).setVisible(true);
            }
        });
        rightPanel.add(newEdgeBtn);
        
        
        //Gráf paraméter kijelző
        dataLabel = new JLabel();
        dataLabel.setText(buildDataLabelText());
        
        rightPanel.add(dataLabel);
        setVisible(true);

    }
    
    /*
     * A gráf paramétereiből épít egy a Stringet amit a dataLabelben jelenít meg a program
     */
    private String buildDataLabelText(){
        String text = new String("<html>");
        
        if(graphLogic.isDirected())
            text += "Irányított";
        else
            text += "Irányítatlan";
        
        text += "<br>";
        
        if(graphLogic.isWeightened())
            text += "Súlyozott";
        else
            text += "Súlyozatlan";
        
        text += "<br>";
        
        if(graphLogic.isTree())
            text += "Fa";
        else
            text += "Nem fa";
        
        text += "<br>";
        
        text += "Csúcsok száma: " + graphLogic.getNodeCount();
        
        text += "<br>";
        
        text += "Élek száma: " + graphLogic.getEdgeCount();
        
        text+= "</html>";
        
        return text;
    }
    
    /*
     * Frissíti az összes grafikai elem tartalmát
     */
    public void updateWindow(JFrame context){
        canvas.repaint();

        dataLabel.setText(buildDataLabelText());
        
        edgesModel.removeAllElements();
                        
        ArrayList<Edge> ed = graphLogic.getAllEdges();
        //System.out.println("All edges: " + ed.size());
        for(Edge edge : ed){
            edgesModel.addElement(edge);
        }
        
        edgesList.removeAll();
        edgesList.setModel(edgesModel);
        
        nodesModel.removeAllElements();
                        
        ArrayList<Node> no = graphLogic.getAllNodes();
        //System.out.println("All nodes: " + no.size());
        for(Node node : no){
            nodesModel.addElement(node);
        }
        nodesList.removeAll();
        nodesList.setModel(nodesModel);

        context.repaint();   
        //System.out.println("NEW NODE PAINTED");
    }
    
    /**
     * Új gráf létrehozó ablak megnyitása
     */
    private AbstractAction newGraphAction =
            new AbstractAction("Új gráf") {
        @Override
        public void actionPerformed(ActionEvent e) {
            new NewGraphWindow(context, graphLogic).setVisible(true);            
        }
    };
    
    /**
     * Gráf betöltő fájlkezelő ablak megnyitása
     */
    private AbstractAction loadGraphAction =
            new AbstractAction("Gráf betöltése") {
        @Override
        public void actionPerformed(ActionEvent e) {
            fc = new JFileChooser();
            if(fc.showOpenDialog(fc) != JFileChooser.CANCEL_OPTION){
                file = fc.getSelectedFile();
                try {
                    graphLogic.loadGraph(file.getAbsolutePath());
                } catch (IOException ex) {
                    Logger.getLogger(GrafRajzWindow.class.getName()).log(Level.SEVERE, null, ex);
                } catch (ClassNotFoundException ex) {
                    Logger.getLogger(GrafRajzWindow.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };
    };
    
    /**
     * Gráf elmentő fájlkezelő ablak megnyitása
     */
    private AbstractAction saveGraphAction =
            new AbstractAction("Gráf mentése") {
        @Override
        public void actionPerformed(ActionEvent e) {
            fc = new JFileChooser();
            if(fc.showSaveDialog(fc) != JFileChooser.CANCEL_OPTION){
                file = fc.getSelectedFile();
                try {
                    graphLogic.saveGraph(file.getAbsolutePath());
                } catch (IOException ex) {
                    Logger.getLogger(GrafRajzWindow.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };
    };
    
    /**
     * Gráf mélységi bejárása
     */
    private AbstractAction bejarasAction =
            new AbstractAction("Gráf bejárása") {
        @Override
        public void actionPerformed(ActionEvent e) {
            if(graphLogic.isDirected()){
                graphLogic.getAlgo().melysegiBejaras(graphLogic.getGraph());
                updateWindow(context);
            }
        };
    };
}